/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package search;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Stack;
import mapapp.ConnectToDatabase;
import mapapp.Statie;

/**
 *
 * @author Cookie
 */
public class AStar {

ArrayList<TraseuInfo> open;
ArrayList<TraseuInfo> closed;

 final int MAX = 1000; // maximum number of connections
// This array holds the flight information.
    ArrayList<TraseuInfo> trasee =new ArrayList<TraseuInfo>();
    //TraseuInfo trasee[] = new TraseuInfo[MAX];
    //int numTrasee = 0; // number of entries in flight array

    public Stack btStack = new Stack(); // backtrack stack




// Initialize the flight database.
public void setup()
{
    ConnectToDatabase connection= new ConnectToDatabase();
    java.sql.PreparedStatement statement=null;
    ResultSet result=null;

    try{
              statement = connection.getConnection().prepareStatement("SELECT * FROM `grafstatii`");
              result = statement.executeQuery();
              while (result.next()) {
              String from=result.getString(2);
              String to=result.getString(3);
              TraseuInfo ti=new TraseuInfo(from,to);
              addTraseu(ti);
            }


        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }finally
    {
        try
        {
            if (result  != null)
                result.close();
            if (statement  != null)
                statement.close();
            if (connection  != null)
                connection.close();
        }
        catch (SQLException e)
        {
            // ignore
        }
    }


}
// Put flights into the database.
void addTraseu(TraseuInfo ti)
{

    trasee.add(ti);
}

public ArrayList<String> route(String to)
{
    ArrayList<String> statii=new ArrayList<String>();
    String numeStF=null;
    String numeStT=null;
    Stack rev = new Stack();
    double dist = 0;
    TraseuInfo ti;
    int num = btStack.size();
    // Reverse the stack to display route.
    for(int i=0; i < num; i++)
    rev.push(btStack.pop());

    System.out.print("De la statia ");
    for(int i=0; i < num; i++)
    {
    ti = (TraseuInfo) rev.pop();

    ConnectToDatabase connection= new ConnectToDatabase();
    java.sql.PreparedStatement statement1=null;
    java.sql.PreparedStatement statement2=null;
    ResultSet result1=null;
    ResultSet result2=null;


    try{
              statement1 = connection.getConnection().prepareStatement("SELECT * FROM `toatestatiile` WHERE `id_statie` LIKE "+ti.IDfrom+"");
              statement2 = connection.getConnection().prepareStatement("SELECT * FROM `toatestatiile` WHERE `id_statie` LIKE "+ti.IDto+"");
              result1 = statement1.executeQuery();
              result2 = statement2.executeQuery();
              while (result1.next()) {
              numeStF=result1.getString(2);

            }
              while (result2.next()) {
              numeStT=result2.getString(2);

            }


        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }finally
        {
        try
        {
            if (result1  != null)
                result1.close();
            if (statement1  != null)
                statement1.close();
             if (result2  != null)
                result2.close();
            if (statement2  != null)
                statement2.close();
            if (connection  != null)
                connection.close();
        }
        catch (SQLException e)
        {
            // ignore
        }
        }

    System.out.print(numeStF + " la statia ");
    statii.add(numeStF);
    dist += ti.distance;
    }
    System.out.println(numeStT);
    statii.add(numeStT);
    System.out.printf("Distanta parcursa este %.2f km" , dist/1000 );
    System.out.println();

    return statii;
}
public double match(String from, String to)
{
   for(int i=trasee.size()-1; i>=0; i--)
   {
   if(trasee.get(i).IDfrom.equals(from) && trasee.get(i).IDto.equals(to) && !trasee.get(i).skip)
   {
      trasee.get(i).skip = true; // prevent reuse
      return trasee.get(i).distance;
   }
   }
        return 0; // not found
}
// Given from, find any connection.
TraseuInfo find(String from)
{
    open = new ArrayList<TraseuInfo>();
    closed = new ArrayList<TraseuInfo>();



    int post=-1;
    double dist=MAX;
   for(int i=0; i < trasee.size(); i++)
   {
        open.add(trasee.get(i));
      if(trasee.get(i).IDfrom.equals(from) && !trasee.get(i).skip)
      {
          if(euristica(trasee.get(i).IDfrom,trasee.get(i).IDto)+drum(trasee.get(i).IDfrom,trasee.get(i).IDto)<dist)
          {
            post=i;
            dist=trasee.get(i).distance;
          }
          if(post==-1){
           TraseuInfo ti = new TraseuInfo(trasee.get(post).IDfrom,trasee.get(post).IDto);
           trasee.get(post).skip = true; // prevent reuse
           open.remove(trasee.get(post));
           closed.add(trasee.get(post));
           return ti;
          }
      }
   }
return null;
}

// Determine if there is a route between from and to.
public void isRoute(String from, String to)
{
    double dist;
    TraseuInfo ti;
    // See if at destination.
    dist = match(from, to);
    if(dist != 0) {
    btStack.push(new TraseuInfo(from, to));
    return;
}
// Try another connection.
   ti = find(from);
   if(ti != null) {
     btStack.push(new TraseuInfo(from, to));
     isRoute(ti.IDto, to);
   }
    else if(btStack.size() > 0) {
    // Backtrack and try another connection.
    ti = (TraseuInfo) btStack.pop();
    isRoute(ti.IDfrom, ti.IDto);
}
}
public double euristica(String curent,String fin){

    ConnectToDatabase connection= new ConnectToDatabase();
     java.sql.PreparedStatement statement=null;
     java.sql.PreparedStatement statement1=null;
     ResultSet result,result1;
     double lat = 0,longt = 0,lat1=0,longt1=0;
     int id = 0,id1=0;
    try{
         statement = connection.getConnection().prepareStatement("SELECT * FROM `toatestatiile` WHERE `nume` LIKE "+curent+"");
         statement1 = connection.getConnection().prepareStatement("SELECT * FROM `toatestatiile` WHERE `nume` LIKE "+fin+"");
          result = statement.executeQuery();
          result1=statement1.executeQuery();
          while(result.next()){
               lat=result.getDouble(3);
               longt=result.getDouble(4);
               id=result.getInt(1);
          }
          while(result1.next()){
               lat1=result1.getDouble(3);
               longt1=result1.getDouble(4);
               id1=result1.getInt(1);
          }
    }catch(Exception e){
        e.printStackTrace();
    }
     mapapp.Punct p=new mapapp.Punct(lat,longt);
     Statie curenta=new Statie(p,curent,id);
     mapapp.Punct p1=new mapapp.Punct(lat1,longt1);
     Statie finala=new Statie(p1,fin,id1);
     return p.distance(p1);

}
public double drum (String from,String curent){
     ConnectToDatabase connection= new ConnectToDatabase();
     java.sql.PreparedStatement statement=null;
     java.sql.PreparedStatement statement1=null;
     ResultSet result,result1;
     double lat = 0,longt = 0,lat1=0,longt1=0;
     int id = 0,id1=0;
    try{
         statement = connection.getConnection().prepareStatement("SELECT * FROM `toatestatiile` WHERE `nume` LIKE "+from+"");
         statement1 = connection.getConnection().prepareStatement("SELECT * FROM `toatestatiile` WHERE `nume` LIKE "+curent+"");
          result = statement.executeQuery();
          result1=statement1.executeQuery();
          while(result.next()){
               lat=result.getDouble(3);
               longt=result.getDouble(4);
               id=result.getInt(1);
          }
          while(result1.next()){
               lat1=result1.getDouble(3);
               longt1=result1.getDouble(4);
               id1=result1.getInt(1);
          }
    }catch(Exception e){
        e.printStackTrace();
    }
     mapapp.Punct p=new mapapp.Punct(lat,longt);
     Statie curenta=new Statie(p,from,id);
     mapapp.Punct p1=new mapapp.Punct(lat1,longt1);
     Statie finala=new Statie(p1,curent,id1);
     return p.distance(p1);

}
}



